﻿using BCCommon;
using BCData.Common.Dictionary;
using BCData.OA.BusinessFlowModel.BusinessFlowModel;
using BCData.OA.BusinessFlowModel.BusinessFlowStepModel;
using BCData.OA.Notification.NotificationCategory;
using BCData.OA.PageBusiness.PageBusinessConfig;
using BCData.OA.PageBusiness.PageBusinessMappingDepartment;
using BCData.Sim.Company.Company;
using BCData.Sim.Company.Department;
using BCDto.OA.PageBusiness.PageBusinessMappingDepartment;
using BCEntity.OA.PageBusiness.PageBusinessMappingDepartment;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.OA.PageBusiness.PageBusinessMappingDepartment
{
    public class PageBusinessMappingDepartmentService : IPageBusinessMappingDepartmentService
    {
        private readonly IApplicationContextService applicationContextService;
        private readonly IPageBusinessMappingDepartmentData pageBusinessMappingDepartmentData;
        private readonly ICompanyData companyData;
        private readonly IDepartmentData departmentData;
        private readonly IPageBusinessConfigData pageBusinessConfigData;
        private readonly IDictionaryReferenceData dictionaryReferenceData;
        private readonly IBusinessFlowModelData businessFlowModelData;
        private readonly IBusinessFlowStepModelData businessFlowStepModelData;
        private readonly INotificationCategoryData notificationCategoryData;
        public PageBusinessMappingDepartmentService(IApplicationContextService applicationContextService,
            IPageBusinessMappingDepartmentData pageBusinessMappingDepartmentData,
             ICompanyData companyData,
             IDepartmentData departmentData,
             IPageBusinessConfigData pageBusinessConfigData,
             IDictionaryReferenceData dictionaryReferenceData,
             IBusinessFlowModelData businessFlowModelData,
             IBusinessFlowStepModelData businessFlowStepModelData,
             INotificationCategoryData notificationCategoryData)
        {
            this.applicationContextService = applicationContextService;
            this.pageBusinessMappingDepartmentData = pageBusinessMappingDepartmentData;
            this.companyData = companyData;
            this.departmentData = departmentData;
            this.pageBusinessConfigData = pageBusinessConfigData;
            this.dictionaryReferenceData = dictionaryReferenceData;
            this.businessFlowModelData = businessFlowModelData;
            this.businessFlowStepModelData = businessFlowStepModelData;
            this.notificationCategoryData = notificationCategoryData;
        }

        public bool Exists(long pageBusinessMappingDepartmentId)
        {
            return this.pageBusinessMappingDepartmentData.Exists(pageBusinessMappingDepartmentId).GetAwaiter().GetResult();
        }

        public PageBusinessMappingDepartmentDto Add(PageBusinessMappingDepartmentRequestDto requestDto)
        {
            var entity = CheckRequestData(requestDto);
            entity.BelongCompanyId = applicationContextService.Admin.CompanyId;
            entity.BelongCompanyName = applicationContextService.Admin.CompanyName;
            return this.pageBusinessMappingDepartmentData.Add(entity).GetAwaiter().GetResult().As<PageBusinessMappingDepartmentDto>();
        }
        public PageBusinessMappingDepartmentDto Update(PageBusinessMappingDepartmentPutDto putDto)
        {
            if (!this.Exists(putDto.PageBusinessMappingDepartmentId))
            {
                throw new ArgumentException("此记录不存在");
            }
            var entity = CheckRequestData(putDto);
            entity.PageBusinessMappingDepartmentId = putDto.PageBusinessMappingDepartmentId;
            return this.pageBusinessMappingDepartmentData.Update(entity).GetAwaiter().GetResult().As<PageBusinessMappingDepartmentDto>();
        }

        private PageBusinessMappingDepartmentEntity CheckRequestData(PageBusinessMappingDepartmentRequestDto requestDto)
        {
            if (requestDto.PageBusinessConfigId == 0)
            {
                throw new ArgumentException("页面业务配置为必选项");
            }
            if (requestDto.CompanyId == 0)
            {
                throw new ArgumentException("公司为必选项");
            }
            if (requestDto.DepartmentId == 0)
            {
                throw new ArgumentException("部门为必选项");
            }
            if (!requestDto.IsAllJobTitle)
            {
                if (string.IsNullOrWhiteSpace(requestDto.AllowJobTitle))
                {
                    throw new ArgumentException("非允许所有职位显示时，允许显示职位应最少选择一个");
                }
            }
            if (requestDto.BusinessFlowModelId.HasValue)
            {
                if (!this.businessFlowModelData.Exists(requestDto.BusinessFlowModelId.Value).GetAwaiter().GetResult())
                {
                    throw new ArgumentException("此业务流模型不存在");
                }
            }
            var pageBusinessEntity = this.pageBusinessConfigData.GetEntity(requestDto.PageBusinessConfigId).GetAwaiter().GetResult();
            if (pageBusinessEntity == null)
            {
                throw new ArgumentException("此页面业务配置不存在");
            }
            if (requestDto.BusinessFlowModelId.HasValue)
            {
                var businessFlowStepModelEntities = this.businessFlowStepModelData.GetEntityByPageBusinessConfigId(requestDto.PageBusinessConfigId).GetAwaiter().GetResult();
                if (businessFlowStepModelEntities != null && businessFlowStepModelEntities.Any(p => p.BusinessFlowModelId == requestDto.BusinessFlowModelId))
                {
                    throw new ArgumentException("此页面业务已存在于此业务流模型的步骤中，这样会造成步骤死循环。请修改所选择的业务流模型配置");
                }
            }
            var companyEntity = this.companyData.GetEntity(requestDto.CompanyId).GetAwaiter().GetResult();
            if (companyEntity == null)
            {
                throw new ArgumentException("此公司不存在");
            }
            var departmentEntities = this.departmentData.GetAll(requestDto.CompanyId).GetAwaiter().GetResult();
            if (!departmentEntities.Any(p => p.DepartmentId == requestDto.DepartmentId))
            {
                throw new ArgumentException(string.Format("{0} 下不存在此部门", companyEntity.CompanyName));
            }
            var departmentEntity = departmentEntities.Single(p => p.DepartmentId == requestDto.DepartmentId);
            //if (string.IsNullOrWhiteSpace(departmentEntity.DepartmentFunction))
            //{
            //    throw new ArgumentException("此部门未设置部门职能，请先设置部门职能");
            //}
            List<string> jobTitleList = new List<string>();
            //if (!requestDto.IsAllJobTitle)
            //{
            //    var staffTitleList = dictionaryReferenceData.GetByTypeNameAndParentNameAsync(departmentEntity.DepartmentFunction.Replace("DepartmentFunction_", ""), "StaffTitle").GetAwaiter().GetResult();
            //    string[] titleList = requestDto.AllowJobTitle.Split(',');
            //    foreach (var item in titleList)
            //    {
            //        if (!staffTitleList.Any(p => p.SearchKey == item))
            //        {
            //            throw new ArgumentException(string.Format("此部门不存在员工职位 {0}", item));
            //        }
            //        var jobTitleEntity = staffTitleList.Single(p => p.SearchKey == item);
            //        jobTitleList.Add(jobTitleEntity.ItemValue);
            //    }
            //}
            if (requestDto.IsAutoAssign)
            {
                if (!requestDto.AssignRuleType.HasValue)
                {
                    throw new ArgumentException("自动分配时，分配规则为必选项，请选择分配规则");
                }
            }
            var notificationCategoryEntity = this.notificationCategoryData.GetEntity(requestDto.NotificationCategoryId).GetAwaiter().GetResult();
            if (notificationCategoryEntity == null)
            {
                throw new ArgumentException("此通知分类不存在");
            }
            var entity = requestDto.As<PageBusinessMappingDepartmentEntity>();
            entity.PageBusinessConfigId = pageBusinessEntity.PageBusinessConfigId;
            entity.PageBusinessCode = pageBusinessEntity.PageBusinessCode;
            entity.PageBusinessName = pageBusinessEntity.PageBusinessName;
            entity.CompanyName = companyEntity.CompanyName;
            entity.DepartmentName = departmentEntity.DepartmentName;
            entity.NotificationCategoryId = notificationCategoryEntity.NotificationCategoryId;
            entity.NotificationCategoryCode = notificationCategoryEntity.NotificationCategoryCode;
            entity.NotificationCategoryName = notificationCategoryEntity.NotificationCategoryName;

            if (!entity.IsAllJobTitle)
            {
                entity.AllowJobTitleStr = string.Join(",", jobTitleList);
            }
            if (requestDto.BusinessFlowModelId.HasValue)
            {
                var businessFlowModelEntity = this.businessFlowModelData.GetEntity(requestDto.BusinessFlowModelId.Value).GetAwaiter().GetResult();
                entity.BusinessFlowModelId = businessFlowModelEntity.BusinessFlowModelId;
                entity.BusinessFlowModelName = businessFlowModelEntity.BusinessFlowModelName;
            }

            return entity;
        }
        public bool Delete(long pageBusinessMappingDepartmentId)
        {
            if (!this.Exists(pageBusinessMappingDepartmentId))
            {
                throw new ArgumentException("此记录不存在");
            }

            return this.pageBusinessMappingDepartmentData.Delete(pageBusinessMappingDepartmentId).GetAwaiter().GetResult();
        }

        public PageBusinessMappingDepartmentDto GetEntity(long pageBusinessMappingDepartmentId)
        {
            return this.pageBusinessMappingDepartmentData.GetEntity(pageBusinessMappingDepartmentId).GetAwaiter().GetResult().As<PageBusinessMappingDepartmentDto>();
        }

        public IEnumerable<PageBusinessMappingDepartmentDto> GetList(int companyId)
        {
            return this.pageBusinessMappingDepartmentData.GetList(companyId).GetAwaiter().GetResult().As<IEnumerable<PageBusinessMappingDepartmentDto>>();
        }

        public IEnumerable<PageBusinessMappingDepartmentDto> GetList(int companyId, long pageBusinessConfigId)
        {
            return this.pageBusinessMappingDepartmentData.GetList(companyId, pageBusinessConfigId).GetAwaiter().GetResult().As<IEnumerable<PageBusinessMappingDepartmentDto>>();
        }

        public PageableList<PageBusinessMappingDepartmentDto> Query(int companyId, long pageBusinessConfigId, string pageBusinessName, DateTime? start, DateTime? end, int pageIndex, int pageSize)
        {
            var (list, count) = this.pageBusinessMappingDepartmentData.Query(companyId, pageBusinessConfigId, pageBusinessName, start, end, pageIndex, pageSize).GetAwaiter().GetResult();

            return new PageableList<PageBusinessMappingDepartmentDto>
            {
                Items = list.As<IEnumerable<PageBusinessMappingDepartmentDto>>(),
                Count = count,
                PageIndex = pageIndex,
                PageSize = pageSize
            };
        }
    }
}
